#!/usr/bin/env python

import sys, os, pickle


def _tmpnam ( prefix = '', rand = '' ):
	"""
	tmpnam ( prefix = '', rand = '' ) -> string

	This function creates a random filename.
	You can specify a string ``prefix`` to be added before the random string
	and, to add some more randomization to the process a ``rand`` string.

	It returns a new string containing your ``tmpnam``.

	Requires: :module:hashlib, :module:time and :module:os

	Note: This function has been taken from os3pylib (C) OS3 srl
	"""
	import time, os, hashlib

	m = hashlib.md5 ()
	m.update ( "%s" % time.time () )
	m.update ( "%s" % os.urandom ( 255 ) )
	m.update ( "%s" % os.getpid () )
	m.update ( "%s" % rand )

	fname = "%s%s.tmp" % ( prefix, m.hexdigest () )
	return fname


def _session_load ( sess_id ):
	# Leggo il file della sessione (se esiste) e faccio un dizionario
	fname = "/tmp/%s.txt" % sess_id
	if os.path.isfile ( fname ):
		sess = pickle.loads ( file ( fname, "r" ).read () )
	else:
		sess = {}

	return sess

def _session_save ( sess_id, sess_data ):
	fname = "/tmp/%s.txt" % sess_id
	fname_tmp = _tmpnam ( "/tmp/", sess_id )
	if os.path.isfile ( fname_tmp ): return

	file ( fname_tmp, "w" ).write ( pickle.dumps ( sess_data ) )
	os.rename ( fname_tmp, fname )

def _session_delete ( sess_id ):
	pass

class Session ( object ):
	def __init__ ( self, pyhp, load = _session_load, save = _session_save, delete = _session_delete ):
		self._pyhp = pyhp
		self.data = {}

		self.id = None

		if not load: load = _session_load
		if not save: save = _session_save
		if not delete: delete = _session_delete

		self._save = save
		self._load = load
		self._delete = delete

		self.log = self._pyhp.log.getLogger ( "Session" )

	def start ( self, load = None, save = None, delete = None ):
		if load: self._load = load
		if save: self._save = save
		if delete: self._delete = delete

		num = 0
		cook = None

		# Cerco di leggere il session_id da __PYHP_SESSION
		num = self._pyhp.post.get ( "__PYHP_SESSION", self._pyhp.get.get ( "__PYHP_SESSION" ) )
		self._pyhp.log.critical ( "COOKIE NUM: %s" % num )

		# Se non trovo num, cerco di leggerlo dal cookie "session"
		if not num:
			# Cerco di leggere il session_id dal cookie
			cook = self._pyhp.cookies.get ( "session" )
			if cook:
				num = cook.value

		sys.stderr.write ( """
		***************************************************************************
		SESSION START: NUM: %s
		***************************************************************************
		""" % num )

		if num:
			self.id = num
		else:
			# Se arrivo fino a qui, significa che devo generare un nuovo valore di cookie
			import random, time
			try:
				import hashlib
				md5 = hashlib.md5 ()
			except:
				import md5
				md5 = md5.md5 ()

			random.seed ( time.time () )

			tmp = "%s-%s" % ( time.time (), random.uniform ( 0, 9000 ) )
			md5.update ( tmp )
			self.id = md5.hexdigest ()

		self.data = self._load ( self.id )

		# Setto la sessione nel cookie
		self._pyhp.cookies.create ( "session", self.id )
		# FIXME: leggere la durata in minuti da pyhp.ini (quando ci sara')
		self._pyhp.cookies.set ( "session", "expires", 60 * 60 )


		#self._pyhp.log.critical ( "XXXX   SESSION: id: %s - data: %s" % ( self.id, self.data ) )

	def save ( self ):
		if not self.id: return

		self._save ( self.id, self.data )

	def load ( self ):
		self.data = self._load ( self.id )

	def delete ( self ):
		if not self.id: return
		self._delete ( self.id )
		self.data = {}

